
#include "../mainctrl.h"
#include "../item/CScrollConfig.h"
#include "CUserStorage.h"

void CUserStorage::Clear()
{
    _uiGID = 0;
    _usBagEmptyGridBegin = 0;
    _usWareHouseEmptyGridBegin = 0;
    _shMaxBagGridCount = SYS_DEFAULT_GRID_NUM_BAG;
    _shMaxWareHouseGridCount = SYS_DEFAULT_GRID_NUM_WAREHOUSE;
    _stStorageHash.Clear();
    _astBagGrids.m_iUsedCount = MAX_BAG_GRID_COUNT;
    _astWareHouseGrids.m_iUsedCount = MAX_WAREHOUSE_GRID_COUNT;

    for (int i = 0; i < _astBagGrids.Size(); ++i)
    {
        _astBagGrids[i] = -1;
    }

    for (int i = 0; i < _astWareHouseGrids.Size(); ++i)
    {
        _astWareHouseGrids[i] = -1;
    }
}

size_t CUserStorage::CountSize()
{
    return CStorageHash::CountSize(MAX_BAG_GRID_COUNT + MAX_WAREHOUSE_GRID_COUNT);
}

int CUserStorage::Init(const char* sBuff)
{
    int iRet = 0;

    iRet = _stStorageHash.Init(sBuff, MAX_BAG_GRID_COUNT + MAX_WAREHOUSE_GRID_COUNT);
    CHECK_RETURN(iRet);

    return 0;
}

//inline bool CUserStorage::BagIsFull() const
bool CUserStorage::BagIsFull() const
{
    return ((short)_usBagEmptyGridBegin >= _shMaxBagGridCount);
}

//inline bool CUserStorage::WareHouseIsFull() const
bool CUserStorage::WareHouseIsFull() const
{
    return ((short)_usWareHouseEmptyGridBegin >= _shMaxWareHouseGridCount);
}

bool CUserStorage::BagIsEmpty()
{
    if (_stStorageHash.GetHeadIndex() < 0)
    {
        return true;
    }

    return (GetBagHeadIndex() == -1);
}

bool CUserStorage::WareHouseIsEmpty()
{
    if (_stStorageHash.GetHeadIndex() < 0)
    {
        return true;
    }

    return (GetWareHouseHeadIndex() == -1);
}

void CUserStorage::SetMaxBagGridCount(short shMaxCount)
{
    _shMaxBagGridCount = (unsigned short)(CT_MIN(shMaxCount, MAX_BAG_GRID_COUNT) & 0x7FFF);
}

void CUserStorage::SetMaxWareHouseGridCount(short shMaxCount)
{
    _shMaxWareHouseGridCount = (unsigned short)(CT_MIN(shMaxCount, MAX_WAREHOUSE_GRID_COUNT) & 0x7FFF);
}

int CUserStorage::GetMaxBagGridCount()
{
    return _shMaxBagGridCount;
}

int CUserStorage::GetMaxWareHouseGridCount()
{
    return _shMaxWareHouseGridCount;
}

int CUserStorage::GetFreeGridCount(bool bOnlyBag)
{
    int iCnt = 0;
    for (int i = 0; i < _shMaxBagGridCount; i++)
    {
        if (_astBagGrids[i] < 0)
        {
            iCnt ++;
        }
    }

    if (false == bOnlyBag)
    {
        for (int i = 0; i < _shMaxWareHouseGridCount; i++)
        {
            if (_astWareHouseGrids[i] < 0)
            {
                iCnt ++;
            }
        }
    }

    return iCnt;
}


int CUserStorage::GetBagHeadIndex() const
{
    for (int i = 0; i < _astBagGrids.Size(); ++i)
    {
        if (_astBagGrids[i] >= 0)
        {
            return _astBagGrids[i];
        }
    }

    return -1;
}

int CUserStorage::GetWareHouseHeadIndex() const
{
    for (int i = 0; i < _astWareHouseGrids.m_iUsedCount; ++i)
    {
        if (_astWareHouseGrids[i] >= 0)
        {
            return _astWareHouseGrids[i];
        }
    }

    return -1;
}

int CUserStorage::GetBagNextIndex(unsigned short usPos)
{
    if (usPos >= _shMaxBagGridCount)
    {
        return -1;
    }

    for (int i = usPos + 1; i < _astBagGrids.m_iUsedCount; ++i)
    {
        if (_astBagGrids[i] >= 0)
        {
            return _astBagGrids[i];
        }
    }

    return -1;
}

int CUserStorage::GetWareHouseNextIndex(unsigned short usPos)
{
    if (usPos >= _shMaxWareHouseGridCount)
    {
        return -1;
    }

    for (int i = usPos + 1; i < _astWareHouseGrids.Size(); ++i)
    {
        if (_astWareHouseGrids[i] >= 0)
        {
            return _astWareHouseGrids[i];
        }
    }

    return -1;
}

int CUserStorage::GetGridInfoByIndex(int iIndex, CStorageGrid& stGrid)
{
    if (iIndex < 0 || iIndex >= MAX_BAG_GRID_COUNT + MAX_WAREHOUSE_GRID_COUNT)
    {
        return ERROR_STORAGE_NO_THIS_GRID;
    }

    stGrid = _stStorageHash[iIndex];
    return 0;
}

//获取背包和仓库中同类物品中的第一个,找不到返回错误
int CUserStorage::GetGridByGroupKey(CStorageItemGroupKey& stGoupKey, CStorageGrid& stGrid)
{
    int iIndex = _stStorageHash.HashFind(stGoupKey);
    if (iIndex < 0)
    {
        return ERROR_STORAGE_ITEM_NOT_EXIST;
    }

    stGrid = _stStorageHash[iIndex];
    return 0;
}

//CStorageKey& stKey 值需要设置_ucItemType,   _usStorePos,   _uiItemID
int CUserStorage::GetGridInfoByKey(CStorageKey& stKey, CStorageGrid& stGrid)
{
    int iIndex = _stStorageHash.HashFind(stKey);
    if (iIndex < 0)
    {
        return ERROR_STORAGE_ITEM_NOT_EXIST;
    }

    stGrid = _stStorageHash[iIndex];
    return 0;
}

int CUserStorage::GetGridInfoByPos(bool bIsInBag, unsigned short usPos, CStorageGrid& stGrid)
{
    if (!IsPosValid (bIsInBag, usPos))
    {
        return ERROR_STORAGE_INVALID_POS;
    }

    int iIndex = bIsInBag ? _astBagGrids[usPos] : _astWareHouseGrids[usPos];
    if (iIndex < 0)
    {
        stGrid =  CStorageGrid();
        //构造函数中默认产生背包中的格子,  产生仓库中的格子需要显示赋值
        stGrid._stKey._bIsInBag = bIsInBag;
        stGrid._stKey._usStorePos = usPos;
    }
    else
    {
        stGrid = _stStorageHash[iIndex];
    }

    return 0;
}

//此函数不做叠加操作，如果需要叠加需要调用AddItem函数
int CUserStorage::AddGrid(CStorageGrid& stGrid)
{
    if (stGrid._shCount <= 0)
    {
        return 0;
    }

    if (stGrid._stKey._bIsInBag)
    {
        return AddToBag(stGrid);
    }
    else
    {
        return AddToWareHouse(stGrid);
    }
}

int CUserStorage::AddToBag(CStorageGrid& stGrid)
{
    if (stGrid._shMaxPerGrid <= 0
        || stGrid._shMaxPerGrid < stGrid._shCount)
    {
        return ERROR_STORAGE_MAX_COUNT_PER_GRID;
    }

    if (!BagIsFull())
    {
        //如果外部未指定要添加到格子位置,取第一个未使用的
        if (STORAGE_POS_NOT_OCCUPIED == stGrid._stKey._usStorePos) 
        {
            stGrid._stKey._usStorePos = _usBagEmptyGridBegin;
        }

        // 如果是要加入到指定的格子,先判断
        if (_astBagGrids[stGrid._stKey._usStorePos] != -1)
        {
            return ERROR_BAG_POS_ITEM_EXIST;
        }

        int iIndex = _stStorageHash.HashAlloc(stGrid._stKey);
        if (iIndex < 0)
        {
            return ERROR_STORAGE_ADD_ITEM;
        }

         stGrid._stKey._bIsInBag = true;
        _stStorageHash[iIndex] = stGrid;
        _astBagGrids[stGrid._stKey._usStorePos] = iIndex;
        _usBagEmptyGridBegin = FindNextEmptyGridInBag(CT_MIN(_usBagEmptyGridBegin, stGrid._stKey._usStorePos));
    }
    else
    {
        return ERROR_STORAGE_ADD_FULL;
    }

    return 0;
}

int CUserStorage::AddToWareHouse(CStorageGrid& stGrid)
{
    if (stGrid._shMaxPerGrid <= 0 ||
        stGrid._shMaxPerGrid < stGrid._shCount)
    {
        return ERROR_STORAGE_MAX_COUNT_PER_GRID;
    }

    if (!WareHouseIsFull())
    {
        stGrid._stKey._bIsInBag = false;
        if (STORAGE_POS_NOT_OCCUPIED == stGrid._stKey._usStorePos)
        {
            stGrid._stKey._usStorePos = _usWareHouseEmptyGridBegin;
        }

        // 如果是要加入到指定的格子,先判断
        if (_astWareHouseGrids[stGrid._stKey._usStorePos] != -1)
        {
            return ERROR_WARE_POS_ITEM_EXIST;
        }

        int iIndex = _stStorageHash.HashAlloc(stGrid._stKey);
        if (iIndex < 0)
        {
            return ERROR_STORAGE_ADD_ITEM;
        }

        _stStorageHash[iIndex] = stGrid;
        _astWareHouseGrids[stGrid._stKey._usStorePos] = iIndex;
        _usWareHouseEmptyGridBegin = FindNextEmptyGridInWareHouse(CT_MIN(_usWareHouseEmptyGridBegin, stGrid._stKey._usStorePos));
    }
    else
    {
        return ERROR_STORAGE_WAREHOUSE_IS_FULL;
    }

    return 0;
}

//CStorageGrid &stGrid参数返回原格子物品的所有信息
int CUserStorage::TakeOutGrid(bool bIsInBag, unsigned short usPos, CStorageGrid& stGrid)
{
    int iIndex = -1;
    if (bIsInBag)
    {
        if (usPos >= _shMaxBagGridCount)
        {
            return ERROR_STORAGE_INVALID_POS;
        }

        iIndex = _astBagGrids[usPos];
    }
    else
    {
        if (usPos >= _shMaxWareHouseGridCount)
        {
            return ERROR_STORAGE_INVALID_POS;
        }

        iIndex = _astWareHouseGrids[usPos];
    }

    if (iIndex < 0)
    {
        return ERROR_STORAGE_TAKE_OUT_NO_ITEM;
    }

    stGrid = _stStorageHash[iIndex];

    if (usPos != stGrid._stKey._usStorePos)
    {
        CT_ERROR(("Take out item bagflag: %u, pos: %u, failed. grid pos: %u", bIsInBag, usPos, stGrid._stKey._usStorePos));
        return ERROR_STORAGE_INVALID_POS;
    }

    //清理数据
    _stStorageHash.HashFreeByIndex(iIndex);
    if (bIsInBag)
    {
        _astBagGrids[stGrid._stKey._usStorePos] = -1;
        if (stGrid._stKey._usStorePos < _usBagEmptyGridBegin)
        {
            _usBagEmptyGridBegin = stGrid._stKey._usStorePos;
        }
    }
    else
    {
        _astWareHouseGrids[stGrid._stKey._usStorePos] = -1;
        if (stGrid._stKey._usStorePos < _usWareHouseEmptyGridBegin)
        {
            _usWareHouseEmptyGridBegin = stGrid._stKey._usStorePos;
        }
    }

    return 0;
}

int CUserStorage::ReplaceGrid(bool bIsInBag, unsigned short usPos, CStorageGrid& stNewGrid)
{  
    if (!IsPosValid (bIsInBag, usPos))
    {
        return ERROR_STORAGE_INVALID_POS;
    }

    //检查新的物品是否合法
    if (!stNewGrid.IsValidGrid())
    {
        CT_ERROR(("%d, %d, %d", stNewGrid._stKey._ucItemType, stNewGrid._stKey._uiItemID, stNewGrid._shCount));
        return ERROR_STORAGE_NO_ITEM_CONFIG;
    }

    int iRet = 0;
    int iIndex = bIsInBag ? _astBagGrids[usPos] : _astWareHouseGrids[usPos];
    if (iIndex >= 0)
    {
        CStorageGrid stOldGrid;
        iRet = TakeOutGrid(bIsInBag, usPos, stOldGrid);
        CHECK_RETURN(iRet);
    }
    
    stNewGrid._stKey._bIsInBag = bIsInBag;
    stNewGrid._stKey._usStorePos = usPos;    

    iRet = AddToBag(stNewGrid);
    CHECK_RETURN(iRet);

    return 0;
}

int CUserStorage::GetItemCount(unsigned char ucItemType, unsigned int uiItemID, bool bOnlyCheckBag)
{
    CStorageItemGroupKey stGroupKey;
    stGroupKey.Init(ucItemType, uiItemID);
    int iCount = 0;
    for (int i = _stStorageHash.HashFind(stGroupKey);
        i >= 0;
        i = _stStorageHash.FindNextSameTypeItem(i))
    {
        if (bOnlyCheckBag
             && !_stStorageHash[i]._stKey._bIsInBag)
        {
            continue;
        }
        iCount += _stStorageHash[i]._shCount;
    }

    return iCount;
}

bool CUserStorage::IsAddible(unsigned char ucItemType, unsigned int uiItemID, short shCount, bool bOnlyFillBag)
{
    if (shCount <= 0)
    {
        return false;
    }

    CItemConfigData stItemConfig;
    int iRet = CMainCtrl::m_pstMain->m_stItemMgr.GetConfig(ucItemType, uiItemID, stItemConfig);
    if (iRet || stItemConfig._shMaxCountPerGrid <= 0 || stItemConfig._iUseGrid <= 0)
    {
        CT_ERROR(("%d, %d, %d", iRet, ucItemType, uiItemID));
        return false;
    }

    short shMaxCountPerGrid = stItemConfig._shMaxCountPerGrid;    
    CStorageItemGroupKey stGroupKey;
    stGroupKey.Init(ucItemType, uiItemID);
    for (int i = _stStorageHash.HashFind(stGroupKey);
        i >= 0;
        i = _stStorageHash.FindNextSameTypeItem(i))
    {        
        shCount -= (shMaxCountPerGrid - _stStorageHash[i]._shCount);
        if (shCount <= 0)
        {
            return true;
        }
    }

    int iFreeGridCnt = GetFreeGridCount(bOnlyFillBag);
    if (shCount <= (iFreeGridCnt * shMaxCountPerGrid))
    {
        return true;
    }

    return false;
}

//叠加到背包中, 要么全加入或者全不加入.
int CUserStorage::AddAllItem(unsigned char ucItemType, unsigned int uiItemID, short & shCount, bool bOnlyFillBag)
{
    CItemConfigData stItemConfig;
    int iRet = CMainCtrl::m_pstMain->m_stItemMgr.GetConfig(ucItemType, uiItemID, stItemConfig);
    CHECK_RETURN(iRet);

    short shToAddCnt = 0;
    while (shCount > 0)
    {
        short shAddCount = (shCount > stItemConfig._shMaxCountPerGrid ? stItemConfig._shMaxCountPerGrid : shCount);
        shToAddCnt = shAddCount; 
        iRet = AddItem(ucItemType, uiItemID, shToAddCnt, bOnlyFillBag);
        if ((iRet != 0) || (shToAddCnt != 0))
        {
            CT_INFO(("Add item to bag failed. iRet: %u, item_type: %u, config_id:%u, shCount: %d,leftcount: %u",
                      iRet, ucItemType, uiItemID, shCount, shToAddCnt));
            return ERROR_STORAGE_BAG_IS_FULL;
        }

        shCount -= shAddCount;
    }

    return 0;
}

//尽可能叠加到背包和仓库中, shCount保存未放下的物品数目. (每次添加的物品数shCount要小于shMaxCountPerGrid)
//bOnlyFillBag为真时,只能添加到背包
int CUserStorage::AddItem(unsigned char ucItemType, unsigned int uiItemID, short& shCount, bool bOnlyFillBag)
{
    if (shCount <= 0)
    {
        return 0;
    }

    //获取堆叠配置
    CItemConfigData stConfigData;
    int iRet = CMainCtrl::m_pstMain->m_stItemMgr.GetConfig(ucItemType, uiItemID, stConfigData);
    CHECK_RETURN(iRet);
    if (shCount > (unsigned short)stConfigData._shMaxCountPerGrid)
    {
        return ERROR_STORAGE_ADD_TOO_MANY_ITEM;
    }

    short shMaxCountPerGrid = stConfigData._shMaxCountPerGrid;
    CStorageItemGroupKey stGroupKey;
    stGroupKey.Init(ucItemType, uiItemID);

    bool bNotifyWare = false;
    short & shLeftCount = shCount;
    for (int i = _stStorageHash.HashFind(stGroupKey);
        i >= 0;
        i = _stStorageHash.FindNextSameTypeItem(i))
    {
        if (_stStorageHash[i]._shCount >= shMaxCountPerGrid)
        {
            continue;
        }

        if ((true == bOnlyFillBag)
            && (false == _stStorageHash[i]._stKey._bIsInBag))
        {
            continue;
        }

        if (_stStorageHash[i]._shCount + shLeftCount > shMaxCountPerGrid)
        {
            if (BagIsFull())
            {
                if (true == bOnlyFillBag)
                {
                    return ERROR_STORAGE_BAG_IS_FULL;
                }
                else if (WareHouseIsFull())
                {
                    return ERROR_STORAGE_ADD_FULL;
                }
            }
            else
            {
                shLeftCount -= shMaxCountPerGrid - _stStorageHash[i]._shCount;  //叠加到新的格子
                _stStorageHash[i]._shCount = shMaxCountPerGrid;
                break;
            }
        }
        else
        {
            _stStorageHash[i]._shCount += shLeftCount;   //叠加到已存在的格子
            shLeftCount = 0;
            bNotifyWare = (false == _stStorageHash[i]._stKey._bIsInBag) ? true : false; 
            return 0;
        }
    }

    //没有此类物品或者堆叠都满了
    CStorageGrid stGrid;
    stGrid.Init(ucItemType, uiItemID);
    stGrid._shCount = shLeftCount;

    if (ITEM_TYPE_FRUIT == stGrid._stKey._ucItemType)
    {
        stGrid._iInvalidTime =  CMainCtrl::m_pstMain->m_iNow + MAX_FRUIT_VALIDE_TIME;
    }

    if (false == BagIsFull())
    {
        iRet = AddToBag(stGrid);
        CHECK_RETURN(iRet);
    }
    else
    {
        if (true == bOnlyFillBag)
        {
            return ERROR_STORAGE_BAG_IS_FULL;
        }
        else
        {
            if (WareHouseIsFull())
            {
                return ERROR_STORAGE_ADD_FULL;
            }
            else
            {
                bNotifyWare = true;
                iRet = AddToWareHouse(stGrid);
                CHECK_RETURN(iRet);
            }
        }
    }

    if (bNotifyWare)
    {
        CMainCtrl::m_pstMain->m_stNotifyMgr.Notify(_uiGID, NOTIFY_WARE_INFO);
    }

    shLeftCount = 0;
    return 0;
}

//全部拿出,或者一个都不拿
int CUserStorage::TakeOutItem(unsigned char ucItemType, unsigned int uiItemID, short shCount)
{
    int iCnt = GetItemCount(ucItemType, uiItemID, false);
    if (iCnt < (int)shCount)
    {
        CT_ERROR(("take out item error, item not enough , ItemType: %u, ConfigId: %u, Count: %u RealCnt %d",
                   ucItemType, uiItemID, shCount, iCnt));
        return ERROR_TAKE_OUT_NOT_ENGOUGH;
    }

    short shLeftCount;
    int iRet = TakeOutItem(ucItemType, uiItemID, shCount, shLeftCount);
    CHECK_RETURN(iRet);

    if (shLeftCount > 0)
    {
        CT_ERROR(("take out item error, ItemType: %u, ConfigId: %u, Count: %u left %d",
                   ucItemType, uiItemID, shCount, shLeftCount));
        return ERROR_TAKE_OUT_NOT_ENGOUGH;
    }

    return 0;
}

//如果背包+仓库中物品的数目小于shCount, shLeftCount返回欠缺的数量,
//为了方便金币合成装备时的处理,材料数目不足时,由外层检测记录日志
int CUserStorage::TakeOutItem(unsigned char ucItemType, unsigned int uiItemID, short shCount, short &shLeftCount)
{
    int iRet = 0;

    if (shCount <= 0)
    {
        return 0;
    }

    shLeftCount = shCount;

    //从背包取
    iRet = TakeOutItem(true, ucItemType, uiItemID, shCount, shLeftCount);
    CHECK_RETURN(iRet);

    if (shLeftCount <= 0)
    {
        return 0;
    }

    //不够再从仓库取
    short shFromWareCnt = shLeftCount;
    iRet = TakeOutItem(false, ucItemType, uiItemID, shFromWareCnt, shLeftCount);
    if (iRet != 0)
    {
        CT_ERROR(("take out from ware house error, ret %d, type %d, itemid %u, count %d, has takeout %d" ,
            iRet, ucItemType, uiItemID, shCount, shCount - shLeftCount));
        return iRet;
    }

    //仓库内容更新,发送前台通知.
    if ( (0 != _uiGID) && (shFromWareCnt > shLeftCount))
    {
        CMainCtrl::m_pstMain->m_stNotifyMgr.Notify(_uiGID, NOTIFY_WARE_INFO);
    }

    return 0;
}

//排序
int CUserStorage::SortStorage(bool bIsSortBag)
{
    int iRet = 0;
    CTArray<CStorageGrid, MAX_BAG_GRID_COUNT + MAX_WAREHOUSE_GRID_COUNT> astTempGrids;

    //排序
    for (int i = 0; i < (bIsSortBag ? _shMaxBagGridCount : _shMaxWareHouseGridCount); ++i)
    {
        int iIndex = bIsSortBag ? _astBagGrids[i] : _astWareHouseGrids[i];
        if (iIndex < 0)
        {
            continue;
        }

        CStorageGrid stGrid = _stStorageHash[iIndex];
        int j = 0;
        for (; j < astTempGrids.Size(); ++j)
        {
            if (stGrid._iPosValue > astTempGrids[j]._iPosValue)
            {
                //后移
                for (int k = astTempGrids.m_iUsedCount; k > j; --k)
                {
                    astTempGrids[k] = astTempGrids[k-1];
                }
                break;
            }
            else if (stGrid._iPosValue == astTempGrids[j]._iPosValue)
            {
                if (stGrid._stKey._ucItemType == astTempGrids[j]._stKey._ucItemType
                    && stGrid._stKey._uiItemID == astTempGrids[j]._stKey._uiItemID)
                {
                    if (astTempGrids[j]._shCount < astTempGrids[j]._shMaxPerGrid)
                    {
                        if (stGrid._shCount + astTempGrids[j]._shCount > astTempGrids[j]._shMaxPerGrid) //不够放
                        {
                            stGrid._shCount -= astTempGrids[j]._shMaxPerGrid - astTempGrids[j]._shCount;
                            astTempGrids[j]._shCount = astTempGrids[j]._shMaxPerGrid;
                        }
                        else
                        {
                            astTempGrids[j]._shCount += stGrid._shCount;
                            stGrid._shCount = 0;
                            break;
                        }
                    }
                }
            }
        }

        //清理容器
        CStorageGrid stGridTemp;
        iRet = TakeOutGrid(bIsSortBag, stGrid._stKey._usStorePos, stGridTemp);
        CHECK_RETURN(iRet);

        if (stGrid._shCount <= 0)
        {
            continue;
        }
        else
        {
            astTempGrids[j] = stGrid;
            astTempGrids.m_iUsedCount++;
        }
    }

    //保存数据
    for (int i = 0; i < astTempGrids.Size(); ++i)
    {
        astTempGrids[i]._stKey._usStorePos = (unsigned short)(i & 0x7FFF);

        if (bIsSortBag)
        {
            iRet = AddToBag(astTempGrids[i]);
            CHECK_RETURN(iRet);
        }
        else
        {
            iRet = AddToWareHouse(astTempGrids[i]);
            CHECK_RETURN(iRet);
        }
    }

    return 0;
}

unsigned short CUserStorage::FindNextEmptyGridInBag(unsigned short usPos)
{
    int i = usPos;
    for (; i < _shMaxBagGridCount; ++i)
    {
        if (_astBagGrids[i] < 0)
        {
            break;
        }
    }

    return i;
}

unsigned short CUserStorage::FindNextEmptyGridInWareHouse(unsigned short usPos)
{
    int i = usPos;
    for (; i < _shMaxWareHouseGridCount; ++i)
    {
        if (_astWareHouseGrids[i] < 0)
        {
            break;
        }
    }

    return i;
}

int CUserStorage::TakeOutItem(bool bIsFromBag, unsigned char ucItemType, unsigned int uiItemID, short shCount, short& shLeftCount)
{
    int iRet = 0;
    CStorageItemGroupKey stGroupKey;
    stGroupKey.Init(ucItemType, uiItemID);

    shLeftCount = shCount;
    CTLib::CTArray<unsigned short, MAX_BAG_GRID_COUNT + MAX_WAREHOUSE_GRID_COUNT> astDelGrids;

    for (int i = _stStorageHash.HashFind(stGroupKey);
        i >= 0;
        i = _stStorageHash.FindNextSameTypeItem(i))
    {
        if (bIsFromBag != _stStorageHash[i]._stKey._bIsInBag)
        {
            continue;
        }

        if (_stStorageHash[i]._shCount >= shLeftCount)
        {
            _stStorageHash[i]._shCount -= shLeftCount;
            shLeftCount = 0;
        }
        else
        {
            shLeftCount -= _stStorageHash[i]._shCount;
            _stStorageHash[i]._shCount = 0;
        }

        if (_stStorageHash[i]._shCount == 0)
        {
            astDelGrids.AddOneItem(_stStorageHash[i]._stKey._usStorePos);
        }

        if (0 == shLeftCount)   {  break; }
    }

    //清空格子
    CStorageGrid stGrid;
    for (int i = 0; i < astDelGrids.Size(); ++i)
    {
        iRet = TakeOutGrid(bIsFromBag, astDelGrids[i], stGrid);
        if (iRet)
        {
            CT_ERROR(("%d, %d", iRet, astDelGrids[i]));            
        }
    }

    return 0;
}

int CUserStorage::CheckScrollMaterial(unsigned short usScrollConfigId)
{
    CScrollConfigData stConfigData;
    int iRet = CMainCtrl::m_pstMain->m_stItemMgr.GetScrollConfig(usScrollConfigId, stConfigData);
    CHECK_RETURN(iRet);

    int iCnt;
    for (int i = 0; i < stConfigData._astMaterial.Size(); i++)
    {
        iCnt = GetItemCount(ITEM_TYPE_MATERIAL, stConfigData._astMaterial[i]._usMaterialId);
        if (iCnt < stConfigData._astMaterial[i]._usMaterialCnt)
        {
            return ERROR_EQUIP_MAKE_LACK_ITEM;
        }
    }

    return 0;
}

int CUserStorage::GetScrollGoldCost(unsigned short usScrollConfigId, int &iGoldCost)
{
    CScrollConfigData stConfigData;
    int iRet = CMainCtrl::m_pstMain->m_stItemMgr.GetScrollConfig(usScrollConfigId, stConfigData);
    CHECK_RETURN(iRet);

    iGoldCost = 0;
    int iLackCnt = 0;       //缺少的材料数量
    int iTotalNeedCnt = 0;  //总共需要的材料数量

    int iLackMaterialGold = 0;
    for (int i = 0; i < stConfigData._astMaterial.Size(); i++)
    {
        int iCurCnt = 0;
        iCurCnt = GetItemCount(ITEM_TYPE_MATERIAL, stConfigData._astMaterial[i]._usMaterialId, false);
        if (iCurCnt < stConfigData._astMaterial[i]._usMaterialCnt)
        {
            int iCnt = (stConfigData._astMaterial[i]._usMaterialCnt - iCurCnt);
            CMaterialConfigData stMaterialCfg;
            iRet = CMainCtrl::m_pstMain->m_stItemMgr.GetMaterialConfig(stConfigData._astMaterial[i]._usMaterialId, stMaterialCfg);
            CHECK_RETURN (iRet);

            iLackCnt          += iCnt;
            iLackMaterialGold += iCnt * stMaterialCfg._iGoldSynPrice;
        }

        iTotalNeedCnt += stConfigData._astMaterial[i]._usMaterialCnt;
    }


    if (ITEM_TYPE_EQUIP == stConfigData._ucNewItemType)
    {
        //只算材料的价格
        iGoldCost = (int)((iLackCnt * 1.0 / iTotalNeedCnt) * (stConfigData._uiNeedGold * 4.0 /5.0));
    }
    else if (ITEM_TYPE_REPUTATION == stConfigData._ucNewItemType)  //魔药
    {
        iGoldCost = iLackMaterialGold;
    }
    else    
    {
        iGoldCost += (int)(((iLackCnt * 1.0 / iTotalNeedCnt) * stConfigData._uiNeedGold) + 0.5);
    }

    if (iLackCnt > 0 &&  0 == iGoldCost)   //计算时由于四舍五入可能导致价格为0
    {
        iGoldCost = 1;
    }

    if (iGoldCost < 0)
    {
        CT_ERROR(("usScrollConfigId : %d", iGoldCost));
        iGoldCost = 0;
    }

    return 0;
}

int CUserStorage::MakeItem(CStorageGrid & stScrollGrid, unsigned char ucOpType, bool bScrollNecessary)
{
    if ((ITEM_TYPE_SCROLL != stScrollGrid._stKey._ucItemType)
        || ((true == bScrollNecessary) && (stScrollGrid._shCount < 1)))
    {
        return ERROR_WRONG_ITEM_TYPE;
    }

    int iRet;

    // 先计算所需的材料是否足够
    if (SCROLL_USE_GOLD != ucOpType)
    {
         iRet = CheckScrollMaterial(stScrollGrid._stKey._uiItemID);
        CHECK_RETURN(iRet);
    }


    //材料充足,直接取出来
    CScrollConfigData stConfigData;
    CMainCtrl::m_pstMain->m_stItemMgr.GetScrollConfig(stScrollGrid._stKey._uiItemID, stConfigData);
    for (int i = 0; i < stConfigData._astMaterial.Size(); i++)
    {
        short sLeftCount = 0;
        iRet = TakeOutItem(ITEM_TYPE_MATERIAL, stConfigData._astMaterial[i]._usMaterialId, stConfigData._astMaterial[i]._usMaterialCnt, sLeftCount);
        CHECK_RETURN(iRet);

        if (SCROLL_USE_GOLD != ucOpType)
        {
            if (0 != sLeftCount)
            {
                CT_ERROR(("take out item error, item not enough , material id: %d, needcount: %d,left %d",
                        stConfigData._astMaterial[i]._usMaterialId, stConfigData._astMaterial[i]._usMaterialCnt, sLeftCount));
                return ERROR_TAKE_OUT_NOT_ENGOUGH;
            }
        }
    }

    //取出卷轴
    if (stScrollGrid._shCount > 0)
    {
        if (stScrollGrid._stKey._usStorePos == STORAGE_POS_NOT_OCCUPIED)
        {
            iRet = TakeOutItem(stScrollGrid._stKey._ucItemType, stScrollGrid._stKey._uiItemID, stScrollGrid._shCount);
            CHECK_RETURN(iRet);
        }
        else
        {
            iRet = TakeOutGrid(stScrollGrid._stKey._bIsInBag, stScrollGrid._stKey._usStorePos, stScrollGrid);
            CHECK_RETURN(iRet);
        }
    }

    return 0;
}

int CUserStorage::MoveGrid(CStorageGrid & stGrid, bool bNewInBag, int iNewPos)
{
    if (stGrid.IsEmpty())
    {
        return 0;
    }

    int iRet;
    iRet = TakeOutGrid(stGrid._stKey._bIsInBag, stGrid._stKey._usStorePos, stGrid);
    CHECK_RETURN(iRet);

    stGrid._stKey._usStorePos = iNewPos;
    stGrid._stKey._bIsInBag = bNewInBag;
    iRet = AddGrid(stGrid);
    CHECK_RETURN(iRet);

    return 0;
}

//注意:  入参需保证stGrid1, stGrid2不为空格子, (stGrid1是被拖动的格子, stGrid2是拖到的格子)
int CUserStorage::SwapGrid(CStorageGrid & stGrid1, CStorageGrid & stGrid2)
{
    CStorageGrid stSwapGrid;
    int iRet;

    iRet = TakeOutGrid(stGrid1._stKey._bIsInBag, stGrid1._stKey._usStorePos, stSwapGrid);
    CHECK_RETURN(iRet);

    iRet = TakeOutGrid(stGrid2._stKey._bIsInBag, stGrid2._stKey._usStorePos, stSwapGrid);
    CHECK_RETURN(iRet);

    stSwapGrid = stGrid1;

    //交互同类型物品,进行堆叠
    if ((stGrid1._stKey._ucItemType == stGrid2._stKey._ucItemType)
        && (stGrid1._stKey._uiItemID == stGrid2._stKey._uiItemID))
    {
        unsigned short usTotal = stGrid1._shCount + stGrid2._shCount;
        stGrid1._shCount = (usTotal > stGrid1._shMaxPerGrid) ? stGrid1._shMaxPerGrid : usTotal;
        stGrid2._shCount = usTotal - stGrid1._shCount;
    }

    stGrid1._stKey._bIsInBag   = stGrid2._stKey._bIsInBag;
    stGrid1._stKey._usStorePos = stGrid2._stKey._usStorePos;
    iRet = AddGrid(stGrid1);
    CHECK_RETURN(iRet);

    if (0 == stGrid2._shCount)
    {
        stGrid2.Clear();
        stGrid2._stKey._bIsInBag   = stSwapGrid._stKey._bIsInBag;
        stGrid2._stKey._usStorePos = stSwapGrid._stKey._usStorePos;
        return 0;
    }

    stGrid2._stKey._bIsInBag   = stSwapGrid._stKey._bIsInBag;
    stGrid2._stKey._usStorePos = stSwapGrid._stKey._usStorePos;
    iRet = AddGrid(stGrid2);
    CHECK_RETURN(iRet);

    return 0;
}

//CStorageGrid & stGrid1:  返回交换后int iStorageType1, int iItemPos1的物品信息
int CUserStorage::SwapStorageItemPos(int iStorageType1, int iItemPos1,CStorageGrid & stGrid1,
                                     int iStorageType2, int iItemPos2,CStorageGrid & stGrid2)
{
    int iRet;
    bool bInBagGrid1 = (iStorageType1 == STORAGE_TYPE_BAG);
    bool bInBagGrid2 = (iStorageType2 == STORAGE_TYPE_BAG);

    iRet = GetGridInfoByPos(bInBagGrid1, iItemPos1, stGrid1);
    CHECK_RETURN(iRet);

    iRet = GetGridInfoByPos(bInBagGrid2, iItemPos2, stGrid2);
    CHECK_RETURN(iRet);

    if (stGrid1.IsEmpty())
    {
        stGrid1._stKey._usStorePos = iItemPos2;
        stGrid1._stKey._bIsInBag   = bInBagGrid2;
        return  MoveGrid(stGrid2, bInBagGrid1, iItemPos1);
    }

    if (stGrid2.IsEmpty())
    {
        stGrid2._stKey._usStorePos = iItemPos1;
        stGrid2._stKey._bIsInBag   = bInBagGrid1;
        return  MoveGrid(stGrid1, bInBagGrid2, iItemPos2);
    }

    return SwapGrid(stGrid1, stGrid2);
}

int CUserStorage::SwapToEmptyGrid(unsigned char ucStorageType1, int iItemPos1,CStorageGrid & stGrid1,
                                  unsigned char ucStorageType2, int iItemPos2,CStorageGrid & stGrid2)
{
    if (iItemPos2 == -1)
    {
        iItemPos2 = (ucStorageType2 == STORAGE_TYPE_WARE) ? _usWareHouseEmptyGridBegin : _usBagEmptyGridBegin;
    }

    if (iItemPos1 == -1)
    {
        iItemPos1 = (ucStorageType1 == STORAGE_TYPE_WARE) ? _usWareHouseEmptyGridBegin : _usBagEmptyGridBegin;
    }

    return SwapStorageItemPos(ucStorageType1, iItemPos1, stGrid1,
                              ucStorageType2, iItemPos2, stGrid2);
}


int CUserStorage::MergeToWareHouse()
{
    int iRet = 0;
    for (int i = 0; i < _shMaxWareHouseGridCount; ++i)
    {
        if (_astWareHouseGrids[i] < 0)
        {
            continue;
        }

        CStorageGrid& stGrid = _stStorageHash[_astWareHouseGrids[i]];
        if (stGrid._shMaxPerGrid <= stGrid._shCount)    //已经满了的堆叠
        {
            continue;
        }
        short shCanAddCount = stGrid._shMaxPerGrid - stGrid._shCount;

        short shNowBagCount = GetItemCount(stGrid._stKey._ucItemType, stGrid._stKey._uiItemID, true);
        if (shNowBagCount <= 0)     //背包里没有
        {
            continue;
        }

        short shAddCount = CT_MIN(shCanAddCount, shNowBagCount);
        short shLeftCount = 0;
        iRet = TakeOutItem(true, stGrid._stKey._ucItemType, stGrid._stKey._uiItemID, shAddCount, shLeftCount);
        if (iRet == 0)
        {
            stGrid._shCount += shAddCount - shLeftCount;
        }
    }

    return 0;
}

int CUserStorage::UnLockBagGrid()
{
    if (_shMaxBagGridCount >= MAX_BAG_GRID_COUNT)
    {
        return ERROR_UNLOCK_BAG_GRID_FAIL;
    }

    _shMaxBagGridCount++;

    return 0;
}

int CUserStorage::UnLockWareGrid()
{
    if (_shMaxWareHouseGridCount >= MAX_WAREHOUSE_GRID_COUNT)
    {
        return ERROR_UNLOCK_WAREHOUSE_GRID_FAIL;
    }

    _shMaxWareHouseGridCount++;
    return 0;
}

void CUserStorage::SetEmpty()
{
    _usBagEmptyGridBegin = 0;
    _usWareHouseEmptyGridBegin = 0;
    _stStorageHash.Clear();

    for (int i = 0; i < _shMaxBagGridCount; ++i)
    {
        _astBagGrids[i] = -1;
    }

    for (int i = 0; i < _shMaxWareHouseGridCount; ++i)
    {
        _astWareHouseGrids[i] = -1;
    }
}

int CUserStorage::CombineCrystal (unsigned char ucOldCrystalId, unsigned char ucCombinedId)
{
    int iTotalCount = GetItemCount(ITEM_TYPE_CRYSTAL, ucOldCrystalId, false);
    if (iTotalCount < 2)
    {
        return ERROR_COMB_CRYSTAL_LACK;
    }

    //仓库和背包满了,尽管在某些情况下,合成后是可以放入的, 为了简便处理, 返回错误,提醒用户手动整理.
    if (BagIsFull() && WareHouseIsFull())
    {
        return ERROR_COMB_CRYSTAL_STORAGE_FULL;
    }

    int iRet = TakeOutItem(ITEM_TYPE_CRYSTAL, ucOldCrystalId, 2);
    CHECK_RETURN(iRet);

    short shCount = 1;
    iRet = AddItem(ITEM_TYPE_CRYSTAL, ucCombinedId, shCount, false);
    if (iRet)
    {
        //加入失败后,回退
        shCount = 2;
        int iRet2 = AddItem(ITEM_TYPE_CRYSTAL, ucOldCrystalId, shCount, false);
        if (iRet2)
        {
            CT_ERROR (("%d, %d, %d", iRet, ucOldCrystalId, iRet2));
        }
    }

    return iRet;
}

int CUserStorage::SortOneItem(unsigned char ucItemType, unsigned short uiItemID, short &shCnt)
{
    CTArray<CStorageKey, MAX_BAG_GRID_COUNT + MAX_WAREHOUSE_GRID_COUNT> astDelGrid;

    shCnt = 0;
    CStorageItemGroupKey stGroupKey;
    stGroupKey.Init(ucItemType, uiItemID);

    int iCurIndex = _stStorageHash.HashFind(stGroupKey);
    short shMaxPerGrid = _stStorageHash[iCurIndex]._shMaxPerGrid;
    for (; iCurIndex >= 0; iCurIndex = _stStorageHash.FindNextSameTypeItem(iCurIndex))
    {
        if (_stStorageHash[iCurIndex]._shCount == 0)
        {
            astDelGrid.AddOneItem(_stStorageHash[iCurIndex]._stKey);
            continue;
        }

        if (shMaxPerGrid > _stStorageHash[iCurIndex]._shCount) //不满的话,取其它格子中的物品,将本堆叠满为止
        {
            for (int iBehind = _stStorageHash.FindNextSameTypeItem(iCurIndex);
                  iBehind >=0 ;
                  iBehind = _stStorageHash.FindNextSameTypeItem(iBehind))
            {
                if (_stStorageHash[iCurIndex]._shCount + _stStorageHash[iBehind]._shCount >= shMaxPerGrid)
                {
                    _stStorageHash[iBehind]._shCount -= (shMaxPerGrid - _stStorageHash[iCurIndex]._shCount);
                    _stStorageHash[iCurIndex]._shCount = shMaxPerGrid;
                    break;
                }
                else
                {
                    _stStorageHash[iCurIndex]._shCount += _stStorageHash[iBehind]._shCount;
                    _stStorageHash[iBehind]._shCount = 0;

                }
            }
        }

        shCnt += _stStorageHash[iCurIndex]._shCount;
    }

    //清除已经空出来的格子
    CStorageGrid stGrid;
    int iRet;
    for (int j = 0; j < astDelGrid.Size(); j++)
    {
        iRet = TakeOutGrid(astDelGrid[j]._bIsInBag, astDelGrid[j]._usStorePos, stGrid);
        CHECK_RETURN(iRet);
    }

    return 0;
}

int CUserStorage::AddToOrderedSeq(CStorageGrid & stCrystal, T_ORDERED_CONFIG_ID & astOrderedSeq)
{
    int j = 0;
    for (; j < astOrderedSeq.Size(); ++j)
    {
        if (stCrystal._stKey._uiItemID == astOrderedSeq[j])
        {
            return 0;  //找到相同的直接返回
        }

        CItemConfigData stConfigData;
        int iRet = CMainCtrl::m_pstMain->m_stItemMgr.GetConfig(ITEM_TYPE_CRYSTAL, astOrderedSeq[j], stConfigData);
        CHECK_RETURN(iRet);

        //等级越高, 权值越大. (排序权值由魔晶等级和魔晶属性类型组成)
        if (stCrystal._iPosValue < stConfigData._iPosValue)
        {
            for (int k = astOrderedSeq.m_iUsedCount; k > j; --k)
            {
                astOrderedSeq[k] = astOrderedSeq[k-1];
            }

            astOrderedSeq[j] = stCrystal._stKey._uiItemID;
            astOrderedSeq.m_iUsedCount += 1;
            return 0;
        }
    }

    //新的类型
    if (j == astOrderedSeq.m_iUsedCount)
    {
        astOrderedSeq.AddOneItem(stCrystal._stKey._uiItemID);
    }

    return 0;
}


int CUserStorage::GetOrderedSeq(T_ORDERED_CONFIG_ID & astOrderedSeq)
{
    astOrderedSeq.Clear();

    int iRet;
    int i = _stStorageHash.GetHeadIndex();
    for (; i >=0; i = _stStorageHash.GetNextIndex(i))
    {
        if (_stStorageHash[i]._stKey._ucItemType != ITEM_TYPE_CRYSTAL)
        {
            continue;
        }

        iRet = AddToOrderedSeq(_stStorageHash[i], astOrderedSeq);
        CHECK_RETURN(iRet);
    }

    return 0;
}

//一键合成
int CUserStorage::OneKeyCrystal (CPlayerDetailInfo & stPlayerDetailInfo, unsigned char ucCombinedLevel)
{
    short shCurCnt = 0;  //当前处理的魔晶个数
    T_ORDERED_CONFIG_ID  astOrderedSeq;
    int iRet = GetOrderedSeq(astOrderedSeq);
    CHECK_RETURN(iRet);

    CSplendidAct & stActData = stPlayerDetailInfo._stSplendidAct;

    CStorageItemGroupKey stGroupKey;
    stGroupKey._ucItemType = ITEM_TYPE_CRYSTAL;
    for (int i = 0; i < astOrderedSeq.Size() ; i ++)   //依据魔晶等级从低到高,依次合成
    {
        stGroupKey._uiItemCfgID = astOrderedSeq[i];
        int iIndex = _stStorageHash.HashFind(stGroupKey);
        if (iIndex < 0)
        {
            continue;
        }

        if (_stStorageHash[iIndex]._stKey._ucItemType != ITEM_TYPE_CRYSTAL)
        {
            continue;
        }

        int usConfigId = _stStorageHash[iIndex]._stKey._uiItemID;
        CCrystalConfigData  stConfigData;
        int iRet = CMainCtrl::m_pstMain->m_stItemMgr.GetCrystalConfig(usConfigId, stConfigData);
        CHECK_RETURN(iRet);

        //astOrderedSeq是有序，如果发现当前的魔晶级别比要求合成的高,表示合成完毕
        if (stConfigData._usLevel >= ucCombinedLevel)
        {
            break;
        }

        //先对同一种魔晶进行堆叠
        iRet = SortOneItem(ITEM_TYPE_CRYSTAL, usConfigId, shCurCnt);
        if (iRet)
        {
            CT_ERROR(("Sort crystal: %u failed, iRet: %u, cnt: %u", usConfigId, iRet, shCurCnt));
            return iRet;
        }

        while (shCurCnt > 1)
        {
            //仓库和背包满了,尽管在某些情况下,合成后是可以放入的, 为了简便处理, 返回错误,提醒用户手动整理.
            if (BagIsFull() && WareHouseIsFull())
            {
                return ERROR_COMB_CRYSTAL_STORAGE_FULL;
            }

            iRet = TakeOutItem(ITEM_TYPE_CRYSTAL, usConfigId, 2);
            if (iRet)
            {
                CT_ERROR(("%d, %d, %d", iRet, stPlayerDetailInfo._uiGID, usConfigId));
                break;
            }

            short shCount = 1;
            iRet = AddItem(ITEM_TYPE_CRYSTAL, stConfigData._usConstructCrystalID, shCount, false);
            if (iRet)
            {
                CT_ERROR(("%d, %d, %d", iRet, stPlayerDetailInfo._uiGID, stConfigData._usConstructCrystalID));
                break;
            }

            shCurCnt -= 2;

            //触发精彩活动
            CMainCtrl::m_pstMain->m_stActMgr.TriggerCrystalCombine(stActData, stPlayerDetailInfo._uiGID, stConfigData._usConstructCrystalID, 1); 
        }

        //(排序权值由魔晶等级和魔晶属性类型组成), 合成后新加入的魔晶,肯定加入在当前处理的魔晶后面.
        CStorageGrid stCrystal;
        stCrystal.Init(ITEM_TYPE_CRYSTAL, stConfigData._usConstructCrystalID);
        iRet = AddToOrderedSeq(stCrystal, astOrderedSeq);
        if (iRet)
        {
            CT_ERROR(("%d, %d, %d", iRet, stPlayerDetailInfo._uiGID, stConfigData._usConstructCrystalID));
        }
    }

    return 0;
}

int CUserStorage::GetBagEmptyGridCount()
{
    int iCount = 0;

    for (int i = 0; i < CT_MIN(_astBagGrids.Size(), _shMaxBagGridCount); ++i)
    {
        if (_astBagGrids[i] == -1)
        {
            iCount++;
        }
    }

    return iCount;
}


bool CUserStorage::IsPosValid (bool bIsInBag, unsigned short usPos)
{
    if (bIsInBag)
    {
        if (usPos >= _shMaxBagGridCount)
        {
            return false;
        }
    }
    else
    {
        if (usPos >= _shMaxWareHouseGridCount)
        {
            return false;
        }
    }

    return true;
}


int CUserStorage::TakeOutItemOnGird(bool bIsInBag, unsigned short usPos, short shCount)
{
    if (!IsPosValid(bIsInBag, usPos))
    {
        return ERROR_STORAGE_INVALID_POS;
    }

    int iIndex = bIsInBag ? _astBagGrids[usPos] : _astWareHouseGrids[usPos];
    if (iIndex < 0)
    {
        return ERROR_STORAGE_ITEM_NOT_EXIST;
    }

    if (shCount > _stStorageHash[iIndex]._shCount)
    {
        return ERROR_TAKE_OUT_NOT_ENGOUGH;
    }

    //相同的时候要清除背包格子
    if (shCount == _stStorageHash[iIndex]._shCount)
    {
        CStorageGrid stGrid;
        return TakeOutGrid(bIsInBag, usPos, stGrid);
    }

    _stStorageHash[iIndex]._shCount -= shCount;
    return 0;
}

int CUserStorage::ClearTime (unsigned short usBagPos, int iNewTime)
{
    if (!IsPosValid(true, usBagPos))
    {
        return ERROR_STORAGE_INVALID_POS;
    }

    if (_astBagGrids[usBagPos] < 0)
    {
        return ERROR_STORAGE_ITEM_NOT_EXIST;
    }

    _stStorageHash[_astBagGrids[usBagPos]]._iInvalidTime = iNewTime;
    return 0;
}


bool CUserStorage::IsLevelGiftAvail(short shRoleLevel)
{
    //判断是否有等级礼包可用
    int index = _stStorageHash.GetHeadIndex();
    while(index >= 0)
    {
        CStorageKey & stKey = _stStorageHash[index]._stKey;
        if (ITEM_TYPE_GIFT == stKey._ucItemType)
        {
            CGiftConfigUnit stConfigData;
            int iRet = CMainCtrl::m_pstMain->m_stItemMgr.GetGiftConfig(stKey._uiItemID, stConfigData);
            if (iRet)
            {
                CT_ERROR(("%d, %d", stConfigData._usGiftId, iRet));
            }
            else if (stConfigData._shRequiredLevel <= shRoleLevel)
            {
                return true;
            }
        }

        index = _stStorageHash.GetNextIndex(index);
    }

    return false;
}
